﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using agsXMPP;
using AjaxChatService.Models;
using agsXMPP.protocol.client;
using agsXMPP.protocol.iq.vcard;

namespace AjaxChatService.FacebookMessenger
{
    public class FacebookUtils
    {
        public FacebookUtils()
        {
            // Subscribe to Events
            XmppClientConnections.xmppClientCon.OnLogin += new ObjectHandler(xmppCon_OnLogin);
            XmppClientConnections.xmppClientCon.OnRosterStart += new ObjectHandler(xmppCon_OnRosterStart);
            XmppClientConnections.xmppClientCon.OnRosterEnd += new ObjectHandler(xmppCon_OnRosterEnd);
            XmppClientConnections.xmppClientCon.OnRosterItem +=
                new XmppClientConnection.RosterHandler(xmppCon_OnRosterItem);
            XmppClientConnections.xmppClientCon.OnPresence +=
                new agsXMPP.protocol.client.PresenceHandler(xmppCon_OnPresence);
            XmppClientConnections.xmppClientCon.OnAuthError += new XmppElementHandler(xmppCon_OnAuthError);
            XmppClientConnections.xmppClientCon.OnError += new ErrorHandler(xmppCon_OnError);
            XmppClientConnections.xmppClientCon.OnClose += new ObjectHandler(xmppCon_OnClose);
            XmppClientConnections.xmppClientCon.OnMessage += 
                new agsXMPP.protocol.client.MessageHandler(xmppCon_OnMessage);
        }
        
        private void xmppCon_OnMessage(object sender, agsXMPP.protocol.client.Message msg)
        {
            // ignore empty messages (events)
            if (msg.Body == null)
                return;

            if (XmppClientConnections.messages.Count > 0)
            {
                if (XmppClientConnections.messages.Last().Content.CompareTo(msg.Body) == 0)
                {
                    return;
                }
            }

            FBMessage message = new FBMessage();
            message.Id = msg.From.User;
            message.Content = msg.Body;

            XmppClientConnections.messages.Add(message);

            //listEvents.Items.Add(String.Format("OnMessage from:{0} type:{1}", returnName(msg.From.User), msg.Type.ToString() ));
            //listEvents.Items.Add(msg.Body);
            //listEvents.SelectedIndex = listEvents.Items.Count -1;
        }

        private void xmppCon_OnClose(object sender)
        {
            XmppClientConnections.status = "OnClose Connection closed";
        }

        private void xmppCon_OnError(object sender, Exception ex)
        {
            XmppClientConnections.status = "OnError";
        }

        private void xmppCon_OnAuthError(object sender, agsXMPP.Xml.Dom.Element e)
        {
            XmppClientConnections.status = "OnAuthError";
        }

        private void xmppCon_OnPresence(object sender, agsXMPP.protocol.client.Presence pres)
        {
            if (pres.Type.ToString().CompareTo("available") == 0)
            {
                setStatus(pres.From.User, true);
            }
            else if (pres.Type.ToString().CompareTo("unavailable") == 0)
            {
                setStatus(pres.From.User, false);
            }
        }

        private void setStatus(string id, bool status)
        {
            for (int i = 0; i < XmppClientConnections.contacts.Count; i++)
            {
                if (XmppClientConnections.contacts[i].Id.CompareTo(id) == 0)
                {
                    XmppClientConnections.contacts[i].Status = status;
                }
            }
        }

        private String returnName(String id)
        {
            foreach (FBContact contact in XmppClientConnections.contacts)
            {
                if (contact.Id.CompareTo(id) == 0)
                {
                    return contact.Name;
                }
            }

            return String.Empty;
        }

        private void xmppCon_OnRosterItem(object sender, agsXMPP.protocol.iq.roster.RosterItem item)
        {
            //add contact into contact list
            FBContact contact = new FBContact();
            contact.Id = String.Format(item.Jid.User);
            contact.Name = String.Format(item.Name ?? item.Jid.User);
            contact.Status = false;
            contact.Avatar = "https://graph.facebook.com/" + contact.Id.Substring(1) + "/picture";

            XmppClientConnections.contacts.Add(contact);
        }

        private void xmppCon_OnRosterEnd(object sender)
        {
            //XmppClientConnections.status = "OnRosterEnd";

            // Send our own presence to teh server, so other epople send us online
            // and the server sends us the presences of our contacts when they are
            // available
            XmppClientConnections.xmppClientCon.SendMyPresence();
        }

        private void xmppCon_OnRosterStart(object sender)
        {
            //XmppClientConnections.status = "OnRosterStart";
        }

        private void xmppCon_OnLogin(object sender)
        {
            XmppClientConnections.status = "OnLogin";
        }

        public void Login_Click(string id, string password)
        {
            Jid jidUser = new Jid(id);

            XmppClientConnections.xmppClientCon.Username = jidUser.User;
            XmppClientConnections.xmppClientCon.Server = jidUser.Server;
            XmppClientConnections.xmppClientCon.Password = password;
            XmppClientConnections.xmppClientCon.AutoResolveConnectServer = true;

            XmppClientConnections.xmppClientCon.Open();
        }

        public bool Logout_Click()
        {
            // close the xmpp connection
            XmppClientConnections.xmppClientCon.Close();

            return true;
        }

        public bool Send_Click(FBMessage message)
        {
            // Send a message
            agsXMPP.protocol.client.Message msg = new agsXMPP.protocol.client.Message();
            msg.Type = agsXMPP.protocol.client.MessageType.chat;

            String ID = message.Id;

            if (ID.CompareTo(String.Empty) == 0)
            {
                return false;
            }
            else
            {
                ID = ID + "@chat.facebook.com";
                msg.To = new Jid(ID);
                msg.Body = message.Content;

                XmppClientConnections.xmppClientCon.Send(msg);

                return true;
            }
        }

        private String returnID(String name)
        {
            foreach (FBContact contact in XmppClientConnections.contacts)
            {
                if (contact.Name.CompareTo(name) == 0)
                {
                    return contact.Id;
                }
            }

            return String.Empty;
        }
    }
}
